package employee

import (
	"goskeleton/app/global/variable"
	"goskeleton/app/model"
	"goskeleton/app/utils/data_bind"

	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

func CreateEmployeeFactory(sqlType string) *EmployeeModel {
	return &EmployeeModel{BaseModel: model.BaseModel{DB: model.UseDbConn(sqlType)}}
}

type EmployeeModel struct {
	model.BaseModel
	Name        string `gorm:"column:name" json:"name"`
	ContactInfo string `gorm:"column:contact_info" json:"contact_info"`
	Email       string `gorm:"column:email" json:"email"`
	Address     string `gorm:"column:address" json:"address"`
	Gender      int    `gorm:"column:gender" json:"gender"`
	BirthDate   string `gorm:"column:birth_date" json:"birth_date"`
	IdNumber    string `gorm:"column:id_number" json:"id_number"`
	BankName    string `gorm:"column:bank_name" json:"bank_name"`
	BankAccount string `gorm:"column:bank_account" json:"bank_account"`
	WorkStatus  int    `gorm:"column:work_status" json:"work_status"`
	HireDate    string `gorm:"column:hire_date" json:"hire_date"`

	HasSocialInsurance int `gorm:"column:has_social_insurance" json:"has_social_insurance"`

	ContractType          int    `gorm:"column:contract_type" json:"contract_type"`
	Remarks               string `gorm:"column:remarks" json:"remarks"`
	CreatedAt             string `gorm:"column:created_at" json:"created_at"`
	UpdatedAt             string `gorm:"column:updated_at" json:"updated_at"`
	WorkContractStartTime string `gorm:"column:work_contract_start_time" json:"work_contract_start_time"`
	WorkContractEndTime   string `gorm:"column:work_contract_end_time" json:"work_contract_end_time"`
	DepartmentId          int    `gorm:"column:department_id" json:"department_id"`
	PositionId            int    `gorm:"column:position_id" json:"position_id"`
	DepartmentPathInfo    string `gorm:"column:department_path_info" json:"department_path_info"`
	DepartmentName        string `gorm:"-" json:"department_name"`
	PositionName          string `gorm:"-" json:"position_name"`
	DeleteStatus          int    `gorm:"column:delete_status" json:"delete_status"` // 是否删除 1否 2是
}

// TableName sets the name of the table in the database
func (e *EmployeeModel) TableName() string {
	return "tb_employee"
}

// InsertData 插入数据
func (e *EmployeeModel) InsertData(c *gin.Context) bool {
	var tmp EmployeeModel
	if err := data_bind.ShouldBindFormDataToModel(c, &tmp); err == nil {

		if res := e.Create(&tmp); res.Error == nil {
			return true
		} else {
			variable.ZapLog.Error("EmployeeModel 数据新增出错", zap.Error(res.Error))
		}
	} else {
		variable.ZapLog.Error("EmployeeModel 数据绑定出错", zap.Error(err))
	}
	return false
}

// 根据关键词查询用户表的条数
func (e *EmployeeModel) getCounts() (counts int64) {
	sql := "select  count(*) as counts from tb_employee"
	if _ = e.Raw(sql).First(&counts); counts > 0 {
		return counts
	} else {
		return 0
	}
}

func (e *EmployeeModel) getCountsByWhere(name string, workStatus int, contractType int,
	hireStartDate string, hireEndDate string,
	departmentIds []int,
	positionId int,
) (counts int64) {
	query := e.Model(&EmployeeModel{})
	if len(departmentIds) > 0 {
		query = query.Where("department_id in (?)", departmentIds)
	}
	if positionId > 0 {
		query = query.Where("position_id = ?", positionId)
	}
	if name != "" {
		query = query.Where("name like ?", "%"+name+"%")
	}
	if workStatus > 0 {
		query = query.Where("work_status = ?", workStatus)
	}
	if contractType > 0 {
		query = query.Where("contract_type = ?", contractType)
	}
	if hireStartDate != "" {
		query = query.Where("hire_date >= ?", hireStartDate)
	}
	if hireEndDate != "" {
		query = query.Where("hire_date <= ?", hireEndDate)
	}
	query = query.Where("delete_status = ?", 1)

	if res := query.Count(&counts); res.Error == nil {

		return counts
	} else {
		variable.ZapLog.Error("EmployeeModel 数据查询出错", zap.Error(res.Error))
		return 0
	}

}

func (e *EmployeeModel) UpdateData(c *gin.Context) bool {
	var tmp EmployeeModel
	if err := data_bind.ShouldBindFormDataToModel(c, &tmp); err == nil {
		if res := e.Updates(&tmp); res.Error == nil {
			return true
		} else {
			variable.ZapLog.Error("EmployeeModel 数据更新出错", zap.Error(res.Error))
			return false

		}
	} else {
		variable.ZapLog.Error("EmployeeModel 数据绑定出错", zap.Error(err))
	}
	return false

}

func (e *EmployeeModel) ListData(
	page, limitItems int, order string,
	name string, workStatus int, contractType int,
	hireStartDate string, hireEndDate string,
	departmentIds []int,
	positionId int,
	) (totalCounts int64, tmp []*EmployeeModel) {
	// var tmp []*EmployeeModel
	counts := e.getCountsByWhere(
		name,
		workStatus,
		contractType,
		hireStartDate,
		hireEndDate,
		departmentIds,
		positionId,
	)

	if counts == 0 {
		return 0, nil
	}

	
	// 构建查询条件
	query := e.Model(&EmployeeModel{})
	if len(departmentIds) > 0 {
		query = query.Where("department_id in (?)", departmentIds)
	}
	if positionId > 0 {
		query = query.Where("position_id = ?", positionId)
	}

	if name != "" {
		query = query.Where("name like ?", "%"+name+"%")
	}
	if workStatus > 0 {
		query = query.Where("work_status = ?", workStatus)
	}
	if contractType > 0 {
		query = query.Where("contract_type = ?", contractType)
	}
	if hireStartDate != "" {
		query = query.Where("hire_date >= ?", hireStartDate)
	}
	if hireEndDate != "" {
		query = query.Where("hire_date <= ?", hireEndDate)
	}
	query = query.Where("delete_status = ?", 1)

	if res := query.Limit(limitItems).Offset(page).Order(order).Find(&tmp); res.Error == nil {
		
		return counts, tmp

	} else {
		variable.ZapLog.Error("EmployeeModel 数据查询出错", zap.Error(res.Error))
	}
	return 0, nil
}

func (e *EmployeeModel) ShowOneItem(id int) (tmp *EmployeeModel) {
	if res := e.Where("id = ?", id).First(&tmp); res.Error == nil && tmp.Id > 0 {

		return tmp
	} else {
		variable.ZapLog.Error("EmployeeModel 数据查询出错", zap.Error(res.Error))
	}
	return nil

}

func (e *EmployeeModel) GetEmployeeByIds(ids []int) (tmp []*EmployeeModel) {
	if res := e.Where("id in (?)", ids).Where("delete_status = ?", 1).Find(&tmp); res.Error == nil {
		return tmp
	}
	return nil
}

func (e *EmployeeModel) GetTotalContractTypeStatistics() (totalContractTypeStatistics *TotalContractTypeStatistics) {
	totalContractTypeStatistics = &TotalContractTypeStatistics{}
	var tmp *TotalContractTypeStatistics
	query := e.Model(e)
	query.Select("sum(case when contract_type = 0 then 1 else 0 end) as full_time_num,sum(case when contract_type = 1 then 1 else 0 end) as part_time_num,sum(case when contract_type = 2 then 1 else 0 end) as intern_num")
	query.Where("delete_status = ?", 1)
	if err := query.First(&tmp).Error; err != nil {
		variable.ZapLog.Error("EmployeeModel 数据查询出错", zap.Error(err))
	}
	if tmp != nil {
		totalContractTypeStatistics.FullTimeNum = tmp.FullTimeNum
		totalContractTypeStatistics.PartTimeNum = tmp.PartTimeNum
		totalContractTypeStatistics.InternNum = tmp.InternNum
		totalContractTypeStatistics.TotalNum = tmp.FullTimeNum + tmp.PartTimeNum + tmp.InternNum
	}
	return totalContractTypeStatistics
}

func (e *EmployeeModel) GetTotalPositionStatistics() (totalPositionStatistics []*TotalPositionStatistics) {
	query := e.Model(e)
	query.Select("position_id,count(*) as total_num")
	if err := query.Group("position_id").Find(&totalPositionStatistics).Error; err != nil {
		variable.ZapLog.Error("EmployeeModel 数据查询出错", zap.Error(err))
	}

	return totalPositionStatistics
}

func (e *EmployeeModel) GetAllIdNameByWhere(departmentIds []int, positionId int) (totalCounts int64, tmp []*IdAndName) {

	variable.ZapLog.Info("GetAllIdNameByWhere", zap.Ints("departmentIds", departmentIds), zap.Int("positionId", positionId))
	if positionId == 0 && len(departmentIds) == 0 {
		query := e.Model(e)
		query.Where("delete_status = ?", 1)
		if err := query.Find(&tmp).Error; err != nil {
			variable.ZapLog.Error("EmployeeModel 数据查询出错", zap.Error(err))
		}
		return int64(len(tmp)), tmp
	}
	variable.ZapLog.Info("GetAllIdNameByWhere", zap.Ints("departmentIds", departmentIds), zap.Int("positionId", positionId))
	if positionId > 0 {
		query := e.Model(e)
		query.Where("position_id = ?", positionId)
		query.Where("delete_status = ?", 1)
		if err := query.Find(&tmp).Error; err != nil {
			variable.ZapLog.Error("EmployeeModel 数据查询出错", zap.Error(err))
		}
		totalCounts = int64(len(tmp))
		variable.ZapLog.Info("positData",zap.Any("pd",tmp))
		return totalCounts, tmp
	}else if len(departmentIds) > 0 {
		query := e.Model(e)
		query.Where("department_id in (?)", departmentIds)
		query.Where("delete_status = ?", 1)
		if err := query.Find(&tmp).Error; err != nil {
			variable.ZapLog.Error("EmployeeModel 数据查询出错", zap.Error(err))
		}
		return int64(len(tmp)), tmp
	}
	return 0, nil
}

func (e *EmployeeModel) DeleteData(id int) bool {
	if res := e.Model(e).Where("id = ?", id).Updates(map[string]interface{}{"delete_status": 2}); res.Error == nil {
		return true
	} else {
		variable.ZapLog.Error("EmployeeModel DeleteData 数据更新出错", zap.Int("id", id), zap.Error(res.Error))
	}
	return false
}
